package org.dashboard.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.github.pagehelper.PageInfo;
import org.dashboard.bean.AdUser;
import org.dashboard.bean.JsonResponse;
import org.dashboard.security.JwtTokenUtil;
import org.dashboard.security.JwtUser;
import org.dashboard.service.AdRoleService;
import org.dashboard.service.AdUserService;
import org.dashboard.utils.NameCastTools;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.dubbo.config.annotation.Reference;

import java.util.*;
import javax.servlet.http.HttpServletRequest;


@RestController
@RequestMapping("/user")
public class AdUserController extends BaseController {

    private static final Logger logger = LoggerFactory.getLogger(AdUserController.class);

    @Reference
    private AdUserService adUserService;

    @Reference
    private AdRoleService adRoleService;


    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    private JwtTokenUtil jwtTokenUtil;


    @RequestMapping(value = "/login", method = {RequestMethod.POST, RequestMethod.GET}, produces = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    public JsonResponse login(HttpServletRequest request) {
        String username = request.getParameter("username");
        String password = request.getParameter("password");

        final Authentication authentication = authenticationManager.authenticate(
                new UsernamePasswordAuthenticationToken(username, password)
        );
        SecurityContextHolder.getContext().setAuthentication(authentication);

        JsonResponse jsonResponse = new JsonResponse();
        Map<String, Object> map = new HashMap<>();

        AdUser adUser = adUserService.selectByName(username);
        map.put("user", NameCastTools.objectToMap(adUser));

        List<Map<String, Object>> roles = adRoleService.selectUserRoles(adUser.getUserId());
        map.put("roles", roles);

        final UserDetails userDetails = userDetailsService.loadUserByUsername(username);
        final String token = jwtTokenUtil.generateToken(userDetails);
        map.put("token", token);

        jsonResponse.setData(map);
        jsonResponse.setCode(1);
        jsonResponse.setResult("success");
        return jsonResponse;
    }

    @RequestMapping(value = "/users/search", method = {RequestMethod.POST, RequestMethod.GET}, produces = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    public JsonResponse search(HttpServletRequest request) {
        String criteria = request.getParameter("criteria");
        Integer pageIndex = Integer.parseInt(request.getParameter("pageIndex"));
        Integer pageSize = Integer.parseInt(request.getParameter("pageSize"));

        PageInfo pageInfo = adUserService.selectAdUsersPaged(criteria, pageIndex, pageSize);

        JsonResponse jsonResponse = new JsonResponse();
        Map<String, Object> map = new HashMap<>();

        map.put("items", NameCastTools.listToListMap(pageInfo.getList()));
        map.put("count", pageInfo.getTotal());

        jsonResponse.setData(map);
        jsonResponse.setCode(1);
        jsonResponse.setResult("success");
        return jsonResponse;
    }


    @RequestMapping(value = "/users/add", method = {RequestMethod.POST, RequestMethod.GET}, produces = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    public JsonResponse add(HttpServletRequest request) {
        String userName = request.getParameter("userName");
        String userPwd = request.getParameter("userPwd");
        String userAlias = request.getParameter("userAlias");
        String passwordBase64 = new String(Base64.getEncoder().encode(userPwd.getBytes()));

        AdUser adUser = new AdUser();
        adUser.setUserName(userName);
        adUser.setUserAlias(userAlias);
        adUser.setUserPassword(passwordBase64);

        adUser.setUserId(adUserService.insert(adUser));
        JsonResponse jsonResponse = new JsonResponse();
        jsonResponse.setData(NameCastTools.objectToMap(adUser));

        jsonResponse.setCode(1);
        jsonResponse.setResult("success");
        return jsonResponse;
    }

    @RequestMapping(value = "/users/update", method = {RequestMethod.POST, RequestMethod.GET}, produces = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    public JsonResponse update(HttpServletRequest request) {

        Integer userId = Integer.parseInt(request.getParameter("userId"));
        String userName = request.getParameter("userName");
        String userPwd = request.getParameter("userPwd");
        String userAlias = request.getParameter("userAlias");
        String passwordBase64 = new String(Base64.getEncoder().encode(userPwd.getBytes()));

        AdUser adUser = new AdUser();
        adUser.setUserId(userId);
        adUser.setUserName(userName);
        adUser.setUserAlias(userAlias);
        adUser.setUserPassword(passwordBase64);

        adUserService.updateByPrimaryKeySelective(adUser);
        adUser = adUserService.selectByPrimaryKey(userId);

        JsonResponse jsonResponse = new JsonResponse();
        jsonResponse.setData(NameCastTools.objectToMap(adUser));

        jsonResponse.setCode(1);
        jsonResponse.setResult("success");
        return jsonResponse;
    }


    @RequestMapping(value = "/users/delete", method = {RequestMethod.POST, RequestMethod.GET}, produces = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    public JsonResponse delete(HttpServletRequest request) {
        String userIds = request.getParameter("userIds");
        JSONArray jsonArray = (JSONArray) JSON.parse(userIds);
        ArrayList<Integer> ids = new ArrayList<>();
        if (jsonArray != null) {
            int len = jsonArray.size();
            for (int i = 0; i < len; i++) {
                ids.add(jsonArray.getInteger(i));
            }
        }
        adUserService.deleteByPrimaryKeys(ids);
        return JsonResponse.success();
    }


    @RequestMapping(value = "/users/checkUsrLoginUnique", method = {RequestMethod.POST, RequestMethod.GET}, produces = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    public JsonResponse check(HttpServletRequest request) {
        Integer userId = Integer.parseInt(request.getParameter("userId"));
        String userName = request.getParameter("userName");

        Integer existCount = adUserService.checkUserNameExist(userName, userId);
        return existCount == 0 ? JsonResponse.success() : JsonResponse.failed();
    }
}
